(*%F _fdata *)
(*# call(seg_name => null) *)
(*%E *)
(*# module(implementation=>off) *)
(*# module(init_code=>off) *)
(*# data(seg_name => null) *)
(*# call(o_a_copy => off) *)

DEFINITION MODULE FioAsm;

(*

These routines are intended to replace low-level routines in JPI's FIO.MOD.
FioAsm's routines are optimized through assembly language.

    -- Carl Neiburger
       169 N. 25th St.
       San Jose, Calif. 95116

       CompuServe No. 72336,2257

*)

TYPE
  Handle = CARDINAL;
  AccessType = (Input, Output, InputOutput);

  PathStr  = ARRAY[0..64] OF CHAR;
  PathTail = ARRAY[0..12] OF CHAR;

  FileAttributes = (readonly,hidden,system,volume,directory,archive,ioerror);
  FileAttr = SET OF FileAttributes;
  DirEntry = RECORD
               rsvd : ARRAY[0..20] OF SHORTCARD;
               attr : FileAttr;
               time : CARDINAL;
               date : CARDINAL;
               size : LONGCARD;
               Name : PathTail;
             END;

  TimeType = RECORD
         Year, Month, Day, Hours, Mins, Secs: CARDINAL
  END;

PROCEDURE IOresult() : CARDINAL;
    (* Returns value saved in hidden IOR variable.
       Possible values are:
         2: file not found.
         3: path not found.
         4: too many open files.
         5: access denied (as in writing to a read-only file).
         6: invalid handle.
        12: invalid access.
        15: invalid drive.
        16: trying to remove current directory.
        17: trying to move a file to a different drive or device.
     *)

(* These procedures set IOresult if they fail: *)
PROCEDURE Create(Name: ARRAY OF CHAR) : Handle;
    (* Creates file with specified name *)
    (* If unsuccessful, returns MAX(CARDINAL) *)
    (* Possible errors: 3, 4, 5 *)

PROCEDURE Open (Name: ARRAY OF CHAR; Typ: AccessType ) : Handle;
    (* Opens existing file with specified name and access type *)
    (* If unsuccessful, returns MAX(CARDINAL) *)
    (* Possible errors: 2, 4, 5, 12 *)

PROCEDURE Close (F: Handle): BOOLEAN;
    (* Closes file with specified handle *)
    (* If unsuccessful, returns FALSE *)
    (* Possible error: 6 *)

PROCEDURE Read (F: Handle; VAR Buf: ARRAY OF BYTE; Count: CARDINAL) : CARDINAL;
    (* Returns the number of bytes read from file into Buf, up to a maximum *)
    (* of Count. Example: Result = Read( fi, readbuf, SIZE (readbuf) ); *)
    (* If unsuccessful, returns 0 *)
    (* Possible errors: 5, 6 *)

PROCEDURE Write (F: Handle; Buf: ARRAY OF BYTE; Count: CARDINAL): CARDINAL;
    (* Returns the number of bytes written to file from Buf, up to a maximum *)
    (* of Count. Example: Result = Write( fi, writebuf, SIZE (writebuf) ); *)
    (* If unsuccessful, returns 0 *)
    (* Possible errors: 5, 6 *)

PROCEDURE Rename(Name,NewName : ARRAY OF CHAR): BOOLEAN;
    (* Renames file Name to NewName *)
    (* Can also be used to move a file betwen directories *)
    (* If unsuccessful, returns FALSE *)
    (* Possible errors: 2, 5, 17 *)

PROCEDURE SetFileAttribute(atr: FileAttr; Name: ARRAY OF CHAR): BOOLEAN;
    (* Gives named file a new attribute *)
    (* If unsuccessful, returns FALSE *)
    (* Possible errors: 3, 5 *)

PROCEDURE GetFileAttribute(Name: ARRAY OF CHAR): FileAttr; 
    (* Returns the attribute of named file *)
    (* If unsuccessful, returns FileAttr{ioerror} *)
    (* Possible errors: 3, 5 *)

PROCEDURE Erase (Name: ARRAY OF CHAR): BOOLEAN;
    (* Erases named file *)
    (* If unsuccessful, returns FALSE *)
    (* Possible errors: 2, 5 *)

PROCEDURE RmDir (Name: ARRAY OF CHAR): BOOLEAN;
    (* Removes named directory *)
    (* If unsuccessful, returns FALSE *)
    (* Possible errors: 3, 5, 16 *)

PROCEDURE MkDir (Name: ARRAY OF CHAR): BOOLEAN;
    (* Creates named directory *)
    (* If unsuccessful, returns FALSE *)
    (* Possible errors: 3, 5 *)

PROCEDURE ChDir (Name: ARRAY OF CHAR): BOOLEAN;
    (* Changes from current directory to named directory *)
    (* If unsuccessful, returns FALSE *)
    (* Possible errors: 3 *)

PROCEDURE Seek  (F: Handle; Pos: LONGCARD; VAR OK: BOOLEAN);
    (* Points MS-DOS read-write pointer to Pos *)
PROCEDURE SeekRel  (F: Handle; Pos: LONGINT; VAR OK: BOOLEAN);
    (* Mpves MS-DOS read-write pointer Pos bytes toward end of file *)
PROCEDURE GetPos(F: Handle; VAR OK: BOOLEAN) : LONGCARD;
    (* Returns position of MS-DOS read-write pointer *)
PROCEDURE SeekEOF (F: Handle; VAR OK: BOOLEAN);
    (* Moves MS-DOS read-write pointer to end of file *)
    (* For above 3 procedures, possible error: 6 *)
PROCEDURE EOF(F:Handle; VAR OK: BOOLEAN): BOOLEAN;
    (* TRUE if MS-DOS read-write pointer is at end of file *)
    (* Possible errors: 5, 6, 13 *)
    (* Above four procedures return OK if successful *)

PROCEDURE Truncate(F: Handle): BOOLEAN;
    (* Truncates file at current MS-DOS read-write pointer position *)
    (* If unsuccessful, returns FALSE *)
    (* Possible errors: 5, 6 *)

PROCEDURE SetFileTime(fi: Handle; filetime: LONGCARD): BOOLEAN;
    (* Sets the file time to MS-DOS format value in filetime. *)
    (* See EncodeFileTime below *)
    (* Returns false if unsucessful *)
    (* Possible error: 6 *)

PROCEDURE FileTime(fi: Handle) : LONGCARD;
    (* Returns the file time in MS-DOS format *)
    (* See DecodeFileTime below *)
    (* Returns 0 if unsucessful *)
    (* Possible error: 6 *)

PROCEDURE SetDrive(Dr :SHORTCARD): BOOLEAN;
    (* Selects a new default drive *)
    (* A: = 1, etc. *)
    (* Possible error: 15 *)

(* These procedures do not set IOresult *)
PROCEDURE GetDrive():SHORTCARD;
    (* Returns the current default drive *)
    (* A: = 1, etc. *)

PROCEDURE Drives(): SHORTCARD;
    (* tells how many *)

PROCEDURE GetDir(Drive: SHORTCARD; VAR Name: ARRAY OF CHAR);
    (* Returns the current directory path *)
    (* If invalid drive or if root directory Name = '' *)

PROCEDURE VerifyIsOn(): BOOLEAN;
    (* Reports if the MS-DOS write-verify switch is on *)

PROCEDURE SetVerify(On: BOOLEAN);
    (* Turns the MS-DOS write-verify switch on (TRUE) or off (FALSE) *)

PROCEDURE DecodeFileTime ( filetime: LONGCARD; VAR T: TimeType );
    (* Translates MS-DOS format filetime into TimeType, *)
    (* so you and your program can read it *)
    (* See FileTime above *)

PROCEDURE EncodeFileTime ( T: TimeType ) : LONGCARD;
    (* Translates TimeType into MS-DOS file time format *)
    (* See SetFileTime above *)

PROCEDURE ReadFirstEntry(DirName : ARRAY OF CHAR;
                         Attr    : FileAttr;
                         VAR D   : DirEntry) : BOOLEAN;
    (* Returns information on first file found matching *)
    (* DirName (which may include wildcards) in D.      *)
    (* Will return hidden and system files and directories *)
    (* if they are included in Attr.  Returns FALSE if no *)
    (* matching file is found. See ReadNextEntry. *)

PROCEDURE ReadNextEntry (VAR D   : DirEntry) : BOOLEAN;
    (* Returns subsequent matching files after first is *)
    (* found by ReadFirstEntry, above. Returns FALSE if no *)
    (* matching file is found. *)

PROCEDURE SetDTA( D : ADDRESS );
    (* Assigns the MS-DOS disk transfer area to ADDRESS *)

PROCEDURE GetDTA(): ADDRESS;
    (* Returns address of MS-DOS disk transfer area *)

PROCEDURE DiskFree(dr: SHORTCARD; VAR BytesPerClust : CARDINAL ): LONGCARD;
    (* Returns disk free space in bytes.  BytesPerCluster returns *)
    (* the smallest increment of disk space that can be allocated. *)
    (* Thus a one-bit file will require BytesPerCluster bytes. *)

END FioAsm.
